/**
 * 
 */
package com.hexacta.hrs.domain.feedback;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.vectrics.common.db.AbstractRecordObject;
import org.vectrics.employee.Employee;
import org.vectrics.recruiter.job.JobFunction;


import com.hexacta.hrs.domain.feedback.effort.Effort;
import com.hexacta.hrs.domain.feedback.skills.FeedbackSkill;
import com.hexacta.hrs.domain.feedback.skills.FeedbackSkillType;
import com.hexacta.hrs.domain.feedback.skills.FeedbackSkillsComparator;

/**
 * @author gvilla
 * 
 */
public class Feedback extends AbstractRecordObject {

    private Long id;

    private String period;
    
    private boolean closed;
    
    private Calendar creationDay;
    
    private Calendar lastModifyDay;
    
    private Integer monthsInProject; 
    
    private Set<FeedbackSkill> skills;

    private ScoreType score;

    private FeedbackMotive feedbackMotive;
    
    private JobFunction jobFunctionInProject;

    private Employee reporter;

    private Employee evaluated;

    private Effort effort;

    public String getPeriod() {
		return period;
	}

	public void setPeriod(String period) {
		this.period = period;
	}

	public boolean isClosed() {
		return closed;
	}

	public void setClosed(boolean closed) {
		this.closed = closed;
	}

	public Calendar getCreationDay() {
		return creationDay;
	}

	public void setCreationDay(Calendar creationDay) {
		this.creationDay = creationDay;
	}

	public String getFormatedLastModifyDay(){
		SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
		return sdf.format(this.lastModifyDay.getTime());
		
	}
	
	public Calendar getLastModifyDay() {
		return lastModifyDay;
	}

	public void setLastModifyDay(Calendar lastModifyDay) {
		this.lastModifyDay = lastModifyDay;
	}
	
	public Integer getMonthsInProject() {
		return monthsInProject;
	}

	public void setMonthsInProject(Integer monthsInProject) {
		this.monthsInProject = monthsInProject;
	}

	/**
     * @return the reporter
     */
    public Employee getReporter() {
        return reporter;
    }

    /**
     * @param reporter
     *            the reporter to set
     */
    public void setReporter(final Employee reporter) {
        this.reporter = reporter;
    }

    /**
     * @return the evaluated
     */
    public Employee getEvaluated() {
        return evaluated;
    }

    /**
     * @param evaluated
     *            the evaluated to set
     */
    public void setEvaluated(final Employee evaluated) {
        this.evaluated = evaluated;
    }

    public Feedback() {
    }
    
    public Feedback(String period) {
    	this.period = period;
        skills = new HashSet<FeedbackSkill>();
        for (FeedbackSkillType st : FeedbackSkillType.values()) {
            FeedbackSkill skill = new FeedbackSkill();
            skill.setSkillType(st);
            skills.add(skill);
        }

    }

    /**
     * @param employee
     * @param project
     * @param evaluator
     *            TODO
     * @param jobFunctionInProject; 
     */
    public Feedback(String period, final Employee evaluated, final FeedbackMotive feedbackMotive, final JobFunction jobFunctionInProject, final Employee evaluator) {
        this(period);
        this.evaluated = evaluated;
        this.jobFunctionInProject = jobFunctionInProject;
        this.reporter = evaluator;
        this.feedbackMotive = feedbackMotive;

    }

    /**
	 * @param employee
	 * @param assignedRole
	 * @param evaluator
	 */
	public Feedback(String period, Employee employee, JobFunction assignedRole,
			Employee evaluator) {
		this(period);
		
		this.evaluated = employee;
        this.jobFunctionInProject = assignedRole;
        this.reporter = evaluator;
	}

	/**
     * @return the skill
     */
    public Set<FeedbackSkill> getSkills() {
    	return skills;
    }

    public Set<FeedbackSkill> getSorteredSkills() {
    	List<FeedbackSkill> list = new ArrayList<FeedbackSkill>(skills);
    	Collections.sort(list, new FeedbackSkillsComparator());
    	skills = new LinkedHashSet<FeedbackSkill>(list);
    	return skills;
    }

    
    /**
     * @param skill
     *            the skill to set
     */
    public void setSkills(final Set<FeedbackSkill> skills) {
        this.skills = skills;
    }

    /**
     * @return the score
     */
    public ScoreType getScore() {
        return score;
    }

    /**
     * @param score
     *            the score to set
     */
    public void setScore(final ScoreType score) {
        this.score = score;
    }

    
    
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }

    /**
     * @param id
     *            the id to set
     */
    public void setId(final Long id) {
        this.id = id;
    }

    /**
     * @return the evaluator
     */
    public Employee getEvaluator() {
        return reporter;
    }

    /**
     * @param evaluator
     *            the evaluator to set
     */
    public void setEvaluator(final Employee evaluator) {
        reporter = evaluator;
    }

    /**
     * @return the effort
     */
    public Effort getEffort() {
        return effort;
    }

    /**
     * @param effort
     *            the effort to set
     */
    public void setEffort(final Effort effort) {
        this.effort = effort;
    }

	public JobFunction getJobFunctionInProject() {
		return jobFunctionInProject;
	}

	public void setJobFunctionInProject(JobFunction jobFunctionInProject) {
		this.jobFunctionInProject = jobFunctionInProject;
	}

	public FeedbackMotive getFeedbackMotive() {
		return feedbackMotive;
	}

	public void setFeedbackMotive(FeedbackMotive feedbackMotive) {
		this.feedbackMotive = feedbackMotive;
	}
	
	private String getProsSkill(String feedbackSkillType) {
		for (FeedbackSkill feedbackSkill : this.getSkills()) {
			if (feedbackSkill.getSkillType().name().equalsIgnoreCase(feedbackSkillType)) {
				return feedbackSkill.getPros();
			}
		}
		return null;
	}
	
	private String getConsSkill(String feedbackSkillType) {
		for (FeedbackSkill feedbackSkill : this.getSkills()) {
			if (feedbackSkill.getSkillType().name().equalsIgnoreCase(feedbackSkillType)) {
				return feedbackSkill.getCons();
			}
		}
		return null;
	}
	
	public String getHfytProsSkill() {
		return this.getProsSkill(FeedbackSkillType.HFYT.name());
	}
	
	public String getHfytConsSkill() {
		return this.getConsSkill(FeedbackSkillType.HFYT.name());
	}
	
	public String getHsacProsSkill() {
		return this.getProsSkill(FeedbackSkillType.HSAC.name());
	}
	
	public String getHsacConsSkill() {
		return this.getConsSkill(FeedbackSkillType.HSAC.name());
	}
	
	public String getHiylProsSkill() {
		return this.getProsSkill(FeedbackSkillType.HIYL.name());
	}
	
	public String getHiylConsSkill() {
		return this.getConsSkill(FeedbackSkillType.HIYL.name());
	}
	
	public String getHpProsSkill() {
		return this.getProsSkill(FeedbackSkillType.HP.name());
	}
	
	public String getHpConsSkill() {
		return this.getConsSkill(FeedbackSkillType.HP.name());
	}
	
	public String getEffortScore() {
		return ((this.getEffort() != null) && (this.getEffort().getScoreType() != null)) ? this.getEffort().getScoreType().name() : "Sin definir";
	}
	
	public String getFormatedScore() {
		return (this.getScore() != null) ? this.getScore().getDescription() : "Sin definir";
	}

	/**
	 * @return
	 */
	public boolean isEmpty() {
		
		if (this.getEffort() != null) {
			return false;
		}
		
		if (this.getScore() != null) {
			return false;
		}
		
		for (FeedbackSkill feedbackSkill : this.getSkills()) {
			if ((feedbackSkill.getPros() != null) || (feedbackSkill.getCons() != null)) {
				return false;
			} else {
				continue;
			}
		}
		
		return true;
	}

}
